home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / ABUSESRC.ZIP / AbuseSrc / macabuse / src / particle.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-20  |  5.3 KB  |  260 lines

  1. #include "macs.hpp"
  2. #include "particle.hpp"
  3. #include "view.hpp"
  4. #include "lisp.hpp"
  5. #include "cache.hpp"
  6. #include "jrand.hpp"
  7. #include "dprint.hpp"
  8.  
  9. static int total_pseqs=0;
  10. static part_sequence **pseqs=NULL;
  11. static part_animation *first_anim=NULL,*last_anim=NULL;
  12.  
  13. void free_pframes()
  14. {
  15.   for (int i=0;i<total_pseqs;i++)
  16.     delete pseqs[i];
  17.   if (total_pseqs)
  18.     jfree(pseqs);
  19. }
  20.  
  21. part_frame::~part_frame()
  22. {
  23.   jfree(data);
  24. }
  25.  
  26. void add_panim(int id, long x, long y, int dir)
  27. {
  28.   CONDITION(id>=0 && id<total_pseqs,"bad id for particle animation");
  29.   part_animation *pan=new part_animation(pseqs[id],x,y,dir,NULL);
  30.   if (!first_anim)
  31.     first_anim=last_anim=pan;
  32.   else
  33.   {
  34.     last_anim->next=pan;
  35.     last_anim=pan;
  36.   }  
  37. }
  38.  
  39. void delete_panims()
  40. {
  41.   while (first_anim)
  42.   {
  43.     last_anim=first_anim;
  44.     first_anim=first_anim->next;
  45.     delete last_anim;
  46.   }
  47.   last_anim=NULL;
  48. }
  49.  
  50. int defun_pseq(void *args)
  51. {
  52.   lisp_symbol *sym=(lisp_symbol *)lcar(args);
  53.   if (item_type(sym)!=L_SYMBOL)
  54.   {
  55.     lprint(args);
  56.     dprintf("expecting first arg to def-particle to be a symbol!\n");
  57.     exit(0);
  58.   }
  59.   int sp=current_space;
  60.   current_space=PERM_SPACE;
  61.   set_symbol_number(sym,total_pseqs);   // set the symbol value to the object number
  62.   current_space=sp;
  63.   pseqs=(part_sequence **)jrealloc(pseqs,sizeof(part_sequence *)*(total_pseqs+1),"particle seq array");
  64.  
  65.   args=lcdr(args);
  66.   pseqs[total_pseqs]=new part_sequence(args);
  67.   total_pseqs++;  
  68.   return total_pseqs;
  69. }
  70.  
  71. extern int total_files_open;
  72.  
  73. part_sequence::part_sequence(void *args)
  74. {
  75.   char *fn=lstring_value(lcar(args)); 
  76.   bFILE *fp=open_file(fn,"rb");
  77.   if (fp->open_failure())
  78.   {
  79.     delete fp;
  80.     lprint(args);
  81.     dprintf("\nparticle sequence : Unable to open %s for reading\n",fn);
  82.     dprintf("total files open=%d\n",total_files_open);
  83.  
  84.     FILE *fp=fopen(fn,"rb");
  85.     dprintf("convet = %d\n",fp!=NULL);
  86.     exit(1);
  87.   }
  88.  
  89.   // count how many frames are in the file
  90.   spec_directory sd(fp);
  91.   delete fp;
  92.   tframes=0;
  93.   int i=0;
  94.   for (;i<sd.total;i++)
  95.     if (sd.entries[i]->type==SPEC_PARTICLE) tframes++;
  96.   frames=(int *)jmalloc(sizeof(int)*tframes,"part_frame id list\n");
  97.  
  98.   int on=0;
  99.   for (i=0;i<sd.total;i++)
  100.     if (sd.entries[i]->type==SPEC_PARTICLE)     
  101.       frames[on++]=cash.reg(fn,sd.entries[i]->name,SPEC_PARTICLE,1);
  102.  
  103. }
  104.  
  105. part_frame::part_frame(bFILE *fp)
  106. {
  107.   t=fp->read_long();
  108.   data=(part *)jmalloc(sizeof(part)*t,"particle frame");
  109.   x1=y1=100000; x2=y2=-100000;
  110.   for (int i=0;i<t;i++)
  111.   {
  112.     short x=fp->read_short();
  113.     short y=fp->read_short();
  114.     if (x<x1) x1=x;
  115.     if (y<y1) y1=y;
  116.     if (x>x2) x2=x;
  117.     if (y>y2) y2=x;
  118.     data[i].x=x;
  119.     data[i].y=y;   
  120.     data[i].color=fp->read_byte(); 
  121.   }
  122. }
  123.  
  124. void tick_panims()
  125. {
  126.   part_animation *last=NULL;
  127.   for (part_animation *p=first_anim;p;)
  128.   {
  129.     p->frame++;
  130.     if (p->frame>=p->seq->tframes)
  131.     {
  132.       if (last)
  133.         last->next=p->next;
  134.       else first_anim=first_anim->next;
  135.       if (last_anim==p) last_anim=last;
  136.       part_animation *d=p;
  137.       p=p->next;
  138.       delete d;
  139.     } else 
  140.     {
  141.       last=p;
  142.       p=p->next;
  143.     }
  144.  
  145.   }
  146. }
  147.  
  148. void draw_panims(view *v)
  149. {
  150.   for (part_animation *p=first_anim;p;p=p->next)      
  151.   {
  152.     cash.part(p->seq->frames[p->frame])->draw(screen,p->x-v->xoff()+v->cx1,p->y-v->yoff()+v->cy1,p->dir);
  153.   }
  154. }
  155.  
  156. void part_frame::draw(image *screen, int x, int y, int dir)
  157. {
  158.   short cx1,cy1,cx2,cy2;
  159.   screen->get_clip(cx1,cy1,cx2,cy2);
  160.   if (x+x1>cx2 || x+x2<cx1 || y+y1>cy2 || y+y2<cy1) return ;
  161.  
  162.   part *pon=data;
  163.   cy1-=y;
  164.   cy2-=y;
  165.  
  166.   int i=t;
  167.   while (i && pon->y<cy1) { pon++; i--; }
  168.   if (!i) return ;
  169.   if (dir>0)
  170.   {
  171.     while (i && pon->y<=cy2)
  172.     {
  173.       long dx=x-pon->x;
  174.       if (dx>=cx1 && dx<=cx2)
  175.       *(screen->scan_line(pon->y+y)+dx)=pon->color;
  176.       i--;
  177.       pon++;
  178.     }   
  179.   } else
  180.   {
  181.     while (i && pon->y<=cy2)
  182.     {
  183.       long dx=pon->x+x;
  184.       if (dx>=cx1 && dx<=cx2)
  185.         *(screen->scan_line(pon->y+y)+dx)=pon->color;
  186.       i--;
  187.       pon++;
  188.     }   
  189.   }
  190.  
  191. }
  192.  
  193.  
  194.  
  195.  
  196. void scatter_line(int x1, int y1, int x2, int y2, int c, int s)
  197. {
  198.   short cx1,cy1,cx2,cy2;
  199.   screen->get_clip(cx1,cy1,cx2,cy2);
  200.  
  201.   int t=abs(x2-x1)>abs(y2-y1) ? abs(x2-x1)+1 : abs(y2-y1)+1;
  202.   long xo=x1<<16,yo=y1<<16,dx=((x2-x1)<<16)/t,dy=((y2-y1)<<16)/t,count=0,x,y;
  203.   uchar *sl;
  204.  
  205.   int xm=(1<<s);
  206.   int ym=(1<<s);
  207.   s=(15-s);
  208.  
  209.  
  210.   while (t--)
  211.   {
  212.     x=(xo>>16)+(jrand()>>s)-xm;
  213.     y=(yo>>16)+(jrand()>>s)-ym;
  214.     if (!(x<cx1 || y<cy1 || x>cx2 || y>cy2))
  215.       *(screen->scan_line(y)+x)=c;
  216.     xo+=dx; yo+=dy;
  217.   }
  218.  
  219. }
  220.  
  221.  
  222.  
  223. void ascatter_line(int x1, int y1, int x2, int y2, int c1, int c2, int s)
  224. {
  225.   short cx1,cy1,cx2,cy2;
  226.   screen->get_clip(cx1,cy1,cx2,cy2);
  227.  
  228.  
  229.   int t=abs(x2-x1)>abs(y2-y1) ? abs(x2-x1)+1 : abs(y2-y1)+1;
  230.   long xo=x1<<16,yo=y1<<16,dx=((x2-x1)<<16)/t,dy=((y2-y1)<<16)/t,count=0,x,y;
  231.   uchar *sl;
  232.  
  233.   int xm=(1<<s);
  234.   int ym=(1<<s);
  235.   s=(15-s);
  236.  
  237.   int w=screen->width();
  238.   uchar *addr;
  239.  
  240.  
  241.   while (t--)
  242.   {
  243.     x=(xo>>16)+(jrand()>>s)-xm;
  244.     y=(yo>>16)+(jrand()>>s)-ym;
  245.     if (!(x<=cx1 || y<=cy1 || x>=cx2 || y>=cy2))
  246.     {
  247.       addr=screen->scan_line(y)+x;
  248.       *addr=c1;
  249.       *(addr+w)=c2;
  250.       *(addr-w)=c2;
  251.       *(addr-1)=c2;
  252.       *(addr+1)=c2;
  253.     }
  254.     xo+=dx; yo+=dy;
  255.   }
  256.  
  257. }
  258.  
  259.  
  260.